package gui;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.rmi.RemoteException;

import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
import javax.swing.border.LineBorder;

import server.Cell;
import server.Server;
import world.LoadState;

public class InformationPanel extends JPanel {

	private Server viewServer;
	private WorldViewPanel view;
	private int[] oldMem;
	
	private JPanel worldInfo;
	private JPanel critterInfo;
	
	private JPanel worldTitle;
	private JPanel worldLabels;
	private CurrentRulePanel rulePanel;
	private JPanel critterTitle;
	private JPanel critterLabels;
	
	private JLabel time;
	private JLabel plants;
	private JLabel critters;
	private JLabel[] memLabels;

	private final Color bkg = new Color(255,99,71);
	
	public InformationPanel(Server server, WorldViewPanel worldView){
		viewServer = server;
		view = worldView;
		
		setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
		
		worldInfo = new JPanel();
		worldInfo.setLayout(new BoxLayout(worldInfo, BoxLayout.Y_AXIS));
		worldInfo.setBorder(new LineBorder(bkg, 3));
		critterInfo = new JPanel();
		critterInfo.setLayout(new BoxLayout(critterInfo, BoxLayout.Y_AXIS));
		critterInfo.setBorder(new LineBorder(bkg, 3));
		worldTitle = new JPanel();
		worldLabels = new JPanel();
		rulePanel = new CurrentRulePanel();
		critterTitle = new JPanel();
		critterLabels = new JPanel();
		
		add(worldInfo);
		add(critterInfo);
		
		worldTitle.add(new JLabel("World state:"));
		worldInfo.add(worldTitle);
		worldInfo.add(worldLabels);//for JLabels
		critterTitle.add(new JLabel("Current critter:"));
		critterInfo.add(critterTitle);
		critterInfo.add(rulePanel);
		critterInfo.add(critterLabels);//for JLabels
		makeJLabels();
		addJLabels();
		

		worldTitle.setBackground(bkg);
		worldTitle.setMaximumSize(new Dimension(500, 20));
		critterTitle.setBackground(bkg);
		worldInfo.setBackground(bkg);
		critterInfo.setBackground(bkg);
	}
	
	private void makeJLabels(){
		time = new JLabel("Time steps completed: 0");
		plants = new JLabel("Plants: 0");
		critters = new JLabel("Critters : 0");
		memLabels = new JLabel[5];
		memLabels[0] = new JLabel("Memory length: ");
		memLabels[1] = new JLabel("Defense: ");
		memLabels[2] = new JLabel("Offense: ");
		memLabels[3] = new JLabel("Size: ");
		memLabels[4] = new JLabel("Energy: ");
	}
	
	private void addJLabels(){
		worldLabels.add(time);
		worldLabels.add(plants);
		worldLabels.add(critters);
		for(int i = 0; i <= 4; i++)
			critterLabels.add(memLabels[i]);
	}
	
	public void paintComponent(Graphics g) {
		g.setColor(bkg);
		g.fillRect(0, 0, getWidth(), getHeight());
		try {
			time.setText("Time steps completed: " + viewServer.stepsCount());
		} catch (RemoteException e) {}
		try {
			plants.setText("Plants: " + viewServer.numPlants());
		} catch (RemoteException e) {}
		try {
			critters.setText("Critters: " + viewServer.numCritters());
		} catch (RemoteException e) {}
		final Cell cell = view.getSelectedCell();
		if (cell != null) {
			final LoadState ruleState = new LoadState();
			SwingWorker<int[], Object> updater = new SwingWorker<int[], Object>() {
				protected int[] doInBackground() throws Exception {
					return viewServer.getCritterMemory(cell.critId());
				}

				protected void done() {
					int[] critMem;
					try {
						critMem = get();
					} catch (Exception e) {
						critMem = oldMem;
					}
					if (critMem != null && critMem.length > 0) {
						memLabels[0].setText("Memory length: " + critMem[0]);
						memLabels[1].setText("Defense: " + critMem[1]);
						memLabels[2].setText("Offense: " + critMem[2]);
						memLabels[3].setText("Size: " + critMem[3]);
						memLabels[4].setText("Energy: " + critMem[4]);
						oldMem = critMem;
					} else {
						memLabels[0].setText("Memory length: ");
						memLabels[1].setText("Defense: ");
						memLabels[2].setText("Offense: ");
						memLabels[3].setText("Size: ");
						memLabels[4].setText("Energy: ");
						rulePanel.updateRule(null);
						ruleState.failed();
					}
				}
			};
			updater.execute();
			if (ruleState.successful()) {
				SwingWorker<String, Object> ruleUpdater = new SwingWorker<String, Object>() {
					protected String doInBackground() throws Exception {
						return viewServer.getCritterCurrentRule(cell.critId());
					}

					protected void done() {
						try {
							rulePanel.updateRule(get());
						} catch (Exception e) {
							rulePanel.updateRule("Server error");
						}
					}
				};
				ruleUpdater.execute();
			}
		} else{
			memLabels[0].setText("Memory length: ");
			memLabels[1].setText("Defense: ");
			memLabels[2].setText("Offense: ");
			memLabels[3].setText("Size: ");
			memLabels[4].setText("Energy: ");
			rulePanel.updateRule(null);
		}
	}
}
